/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package SecureUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;

/**
 *
 * @author Gwang
 */
public class Packer {
    public enum DataType {INTEGER, BYTE, STRING, BYTES, LONG};
    class Element{
        DataType type;
        Object obj;
        public Element(Packer.DataType t, Object i){
            type = t;
            obj = i;
        }
    }
    private ArrayList<Element> elements;
    Packer(){
        elements = new ArrayList<Element>();
    }
    void addElement(Packer.DataType t, Object i) throws Exception{
        elements.add(new Element(t,i));
    }

    public byte[] pack() throws Exception{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos =  new DataOutputStream(baos);
        for(Element e : elements){
            byte[] bytes;

            if(e.type.equals(DataType.INTEGER)) dos.writeInt((Integer)e.obj);
            else if(e.type.equals(DataType.LONG)) dos.writeLong((Long)e.obj);
            else if(e.type.equals(DataType.BYTE)) dos.writeByte((Byte) e.obj);
            else if (e.type.equals(DataType.BYTES)){
                bytes = (byte[]) e.obj;
                dos.writeInt(bytes.length);
                dos.write(bytes);
            }
            else if(e.type.equals(DataType.STRING)){
                String s =(String) e.obj;
                bytes = s.getBytes();
                dos.writeInt(bytes.length);
                dos.write(bytes);
            }
        }
        return baos.toByteArray();
    }

    public void unpack(byte[] bytes) throws Exception{
         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
         DataInputStream dis = new DataInputStream(bais);

         for(Element e : elements){
            if(e.type.equals(DataType.INTEGER))   e.obj = dis.readInt();
            else if(e.type.equals(DataType.LONG)) e.obj = dis.readLong();
            else if(e.type.equals(DataType.BYTE)) e.obj = dis.readByte();
            else if (e.type.equals(DataType.BYTES)){
               int len = dis.readInt();
               e.obj = new byte[len];
               dis.read((byte[]) e.obj);
            }else if (e.type.equals(DataType.STRING)){
                int len = dis.readInt();
                byte[] strbytes = new byte[len];
                dis.read(strbytes);
                e.obj = new String(strbytes);
            }
         }
    }

}
